﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using HWEngine.Configuration;

namespace HWEngine
{
	public class LetterSetRepository
	{
		private List<LetterSet> _sets = new List<LetterSet>();
		private string _path; 
		
		public LetterSetRepository(string path)
		{
			_path = path;
			Init();
		}

		public LetterSetRepository(LetterSet letters)
		{
			_path = string.Empty;
			_sets.Add(letters);
		}

		public void Init()
		{
			_sets.Clear();
			var dir = Directory.CreateDirectory(_path);
			foreach (var file in dir.GetFiles("*.font").OrderBy(file => file.Name))
			{
				XmlDocument xml = new XmlDocument();
				xml.Load(file.FullName);
				LetterSet set = Serializer.Deserialize<LetterSet>(xml.OuterXml);
				_sets.Add(set);
			}
		}

		public LetterSet Create()
		{
			string fontNameBase = "Font ";
			int fontIndexer = _sets.Count;

			while (!CheckFontName(fontNameBase + fontIndexer))
			{
				++fontIndexer;
			}

			LetterSet s = LetterSet.Create();
			s.FontName = fontNameBase + fontIndexer;
			_sets.Add(s);
			return s;
		}

		public IEnumerable<string> GetNames()
		{
			return _sets.Select(s => s.FontName);
		}

		public LetterSet Get(string name)
		{
			return GetWithNoDefaults(name) ?? _sets.First();
		}

		private LetterSet GetWithNoDefaults(string name)
		{
			return _sets.Find(s => s.FontName == name);
		}

		public LetterSet GetBySystemFontName(string name)
		{
			return _sets.Find(s => s.SystemFontMatchName == name) ?? _sets.First();
		}

		public void Save()
		{
			if (string.IsNullOrEmpty(_path))
			{
				throw new InvalidProgramException("Cannot save without a path. Specify path first.");
			}

			//Delete all existing files
			var dir = Directory.CreateDirectory(_path);
			foreach (var file in dir.GetFiles("*.font"))
			{
				file.Delete();
			}

			//Save all fonts
			foreach (var set in _sets)
			{
				XmlDocument xml = new XmlDocument();
				set.Letters = set.Letters.OrderBy(l=>l.Key).ToList();
				xml.InnerXml = Serializer.Serialize(set);
				xml.Save(GetFileName(set.FontName));
			}
		}

		public bool SetFontName(LetterSet font, string newFontName)
		{
			if (CheckFontName(newFontName))
			{
				font.FontName = newFontName;
				return true;
			}
			return false;
		}

		public void DeleteFont(string fontName)
		{
			var s = GetWithNoDefaults(fontName);
			if (s != null)
			{
				_sets.Remove(s);
			}
		}

		private bool CheckFontName(string fontName)
		{
			return GetWithNoDefaults(fontName) == null;
		}

		private string GetFileName(string fontName)
		{
			int i = 0;
			string suffix = string.Empty;
			while (File.Exists(Path.Combine(_path, fontName + suffix + ".font")))
			{
				suffix = i.ToString();
				++i;
			}
			return Path.Combine(_path, fontName + suffix + ".font");
		}
	}
}
